package com.xj.shop.manage.all.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.xj.shop.manage.all.mapper.CategoryMapper;
import com.xj.shop.manage.all.model.dto.CategoryDTO;
import com.xj.shop.manage.all.model.entity.Category;
import com.xj.shop.manage.all.model.query.CategoryQuery;
import com.xj.shop.manage.all.model.vo.CategoryVO;
import com.xj.shop.manage.all.service.CategoryService;
import io.github.wslxm.springbootplus2.core.base.service.impl.BaseServiceImpl;
import io.github.wslxm.springbootplus2.core.constant.NumberConstant;
import io.github.wslxm.springbootplus2.core.enums.Base;
import io.github.wslxm.springbootplus2.core.utils.BeanDtoVoUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;


/**
 * 类别表 ServiceImpl
 *
 * <p>
 * ::本代码由[兮家小二]提供的代码生成器生成,如有问题,请手动修改 ::作者CSDN:https://blog.csdn.net/qq_41463655
 * </p>
 *
 * @author ws
 * @email 1720696548@qq.com
 * @date 2022-08-24 15:17:19
 */
@Service
public class CategoryServiceImpl extends BaseServiceImpl<CategoryMapper, Category> implements CategoryService {

    @Override
    public List<CategoryVO> tree(CategoryQuery query) {

        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<Category>()
                .eq(StringUtils.isNotBlank(query.getPid()), Category::getPid, query.getPid())
                .in(query.getIds() != null && query.getIds().size() > 0, Category::getId, query.getIds())
                .eq(query.getDisable() != null, Category::getDisable, query.getDisable())
                .orderByAsc(Category::getSort)
                .orderByDesc(Category::getCreateTime);
        List<CategoryVO> listVo = BeanDtoVoUtil.listVo(this.list(queryWrapper), CategoryVO.class);

        // 获取顶级数据
        List<CategoryVO> pListVo = listVo.stream().filter(p -> p.getPid().equals(NumberConstant.ZERO + "")).collect(Collectors.toList());
        // 递归写入下级数据
        for (CategoryVO categoryVO : pListVo) {
            this.nextCategory(listVo, categoryVO);
        }
        return pListVo;
    }

    @Override
    public IPage<CategoryVO> findPage(CategoryQuery query) {
        LambdaQueryWrapper<Category> queryWrapper = new LambdaQueryWrapper<Category>()
                .eq(StringUtils.isNotBlank(query.getPid()), Category::getPid, query.getPid())
                .in(query.getIds() != null && query.getIds().size() > 0, Category::getId, query.getIds())
                .eq(query.getDisable() != null, Category::getDisable, query.getDisable())
                .eq(query.getRoot() != null, Category::getRoot, query.getRoot())
                .orderByDesc(Category::getSort)
                .orderByDesc(Category::getCreateTime);
        Page<Category> page = new Page<>(query.getCurrent(), query.getSize());
        return BeanDtoVoUtil.pageVo(this.page(page, queryWrapper), CategoryVO.class);
    }

    @Override
    public CategoryVO findId(String id) {
        return BeanDtoVoUtil.convert(this.getById(id), CategoryVO.class);
    }

    @Override
    public String insert(CategoryDTO dto) {
        Category entity = dto.convert(Category.class);
        boolean b = this.save(entity);
        return entity.getId();
    }

    @Override
    public boolean upd(String id, CategoryDTO dto) {
        Category entity = dto.convert(Category.class);
        entity.setId(id);
        return this.updateById(entity);
    }

    @Override
    public boolean del(String id) {
        // 删除第三级数据 --> 如果传入id是第一级,获取第二级所有id，并删除第三级数据
        List<Category> list = this.list(new LambdaQueryWrapper<Category>().select(Category::getId).eq(Category::getPid, id));
        if (!list.isEmpty()) {
            List<String> depIds = list.stream().map(Category::getId).collect(Collectors.toList());
            this.removeByIds(depIds);
        }
        // 删除第二级数据+第一级数据
        this.remove(new LambdaQueryWrapper<Category>().and(p ->
                p.eq(Category::getPid, id)
                        .or().eq(Category::getId, id)));
        return this.removeById(id);
    }


    /**
     * 递归
     *
     * @param listVo
     * @param categoryVO
     * @return void
     * @author wangsong
     * @date 2021/9/30 0030 17:17
     * @version 1.0.1
     */
    private void nextCategory(List<CategoryVO> listVo, CategoryVO categoryVO) {
        if (categoryVO.getRoot().equals(Base.DepRoot.V3.getValue())) {
            return;
        }
        for (CategoryVO nextCategoryVO : listVo) {
            if (categoryVO.getId().equals(nextCategoryVO.getPid())) {
                if (categoryVO.getChildren() == null) {
                    categoryVO.setChildren(CollUtil.newArrayList(nextCategoryVO));
                } else {
                    categoryVO.getChildren().add(nextCategoryVO);
                }
                nextCategory(listVo, nextCategoryVO);
            }
        }
    }
}
